package org.example.controller;

import org.example.domain.vo.LoginRequest;
import org.example.pojo.entity.User;
import org.example.result.Result;
import org.example.service.EmailService;
import org.example.service.UserService;
import org.example.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/register")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 用户名校验
     */
    @PostMapping("/checkUsername")
    public Result<?> checkUsername(@RequestParam String username) {
        // 校验用户名不能为空
        if (username == null || username.trim().isEmpty()) {
            return Result.error("用户名不能为空");
        }
        // 校验用户名长度和字符组合，只允许8到16个字母和数字
        if (!username.matches("^[A-Za-z0-9]{8,16}$")) {
            return Result.error("用户名必须由8到16个大小写英文字母和数字组成");
        }
        // 判断用户名是否已经存在
        boolean exists = userService.existsByUsername(username);
        if (exists) {
            return Result.error("该用户名已被使用");
        }
        // 用户名可用，返回成功信息或进行下一步操作
        return Result.success(200);
    }

    /**
     * 密码校验
     */
    @PostMapping("/checkPassword")
    public Result<?> checkPassword(@RequestParam String password) {
        // 校验密码不能为空
        if (password == null || password.trim().isEmpty()) {
            return Result.error("密码不能为空");
        }
        // 密码可用，返回成功信息或进行下一步操作
        return Result.success(200);
    }


    /**
     * 接收用户名与邮箱，发送验证码到邮箱
     */
    @PostMapping("/sendEmailCode")
    public Result<String> sendEmailCode(@RequestParam(value = "email") String email) {
        // 生成随机验证码（例如4位数字）
        String code = userService.generateVerificationCode();
        // 保存验证码，可保存到数据库、Redis或者session中，此处使用简单的内存Map
        userService.saveVerificationCode(email, code);
        // 调用邮箱服务发送验证码
        emailService.sendSimpleMessage("541124703@qq.com", email, "邮箱验证", "您的验证码是：" + code);
        return Result.success("验证码已发送至邮箱，请查收");
    }

    /**
     * 校验用户输入的验证码
     */
    @PostMapping("/verifyEmailCode")
    public Result<String> verifyEmailCode(@RequestParam String username,
                                          @RequestParam String password,
                                          @RequestParam String code,
                                          @RequestParam String email) {
        boolean verified = userService.verifyCode(email, code);
        if (verified) {
            userService.registerNewUser(username, password, email);
            return Result.success("用户注册成功！");
        }
        return Result.error("验证码错误，请重新输入");
    }

    @PostMapping("/login")
    public Result<?> login(@RequestBody LoginRequest loginRequest) {
        String providedToken = loginRequest.getToken();

        // 如果前端传入了 token，则验证其是否存在且未过期
        if (providedToken != null && !providedToken.isEmpty()) {
            // 这里我们存储 token 的 key 约定为 "token:" + token
            String userId = redisTemplate.opsForValue().get("token:" + providedToken);
            if (userId != null) {
                // token 有效，直接返回用户信息
                User user = userService.findById(Long.parseLong(userId));
                if (user != null) {
                    return Result.success(user);
                }
            }
        }

        // token 不存在或无效时，走传统登录流程：校验账号和密码
        String account = loginRequest.getAccount();
        String password = loginRequest.getPassword();

        User user = userService.findByAccount(account);
        if (user == null || !user.getPassword().equals(password)) {
            return Result.error("账号或密码错误");
        }

        // 生成 JWT Token，设置过期时间 5 分钟 = 300000 毫秒
        String token = JwtUtil.generateToken(user.getUsername(), 300_000);
        // 存入 Redis，key 采用 "token:" + token，value 为用户 id，设置过期时间 5 分钟
        redisTemplate.opsForValue().set("token:" + token, user.getId().toString(), 5, TimeUnit.MINUTES);

        // 返回 token 信息（前端可用 token 进行后续请求验证）
        return Result.success(Collections.singletonMap("token", token));
    }
}
